home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / util / sys / QuickROM.lha / quickrom / QuickROM.asm < prev    next >
Encoding:
Assembly Source File  |  1998-05-21  |  10.2 KB  |  326 lines

  1. * QuickROM - uses 68060 or 68040 MMU to remap Kickstart in FAST RAM
  2. *
  3. * First written by Simon N Goodwin October 10th 1996, PUBLIC DOMAIN
  4. *
  5. * Updated January 1997: automatically senses the Kickstart ROM size
  6. * and can be re-assembled for page sizes other than the default 4K.
  7. *
  8. * First Aminet upload = version 36.07, 2 May 1998. Code extended to
  9. * run from a Workbench icon, Aminet update version 36.08, 21st May.
  10. *
  11. * This program works like KSREMAP and ROM2FAST, but it's compatible
  12. * with more systems, smaller than the former, and more capable than
  13. * the latter. Written and tested on a Mark 2 Cyberstorm 68060, more
  14. * than doubling the speed of access to Kickstart code. Also tested
  15. * on GVP G-FORCE 68060, Commodore's 3640 (helps a bit, but hampered
  16. * by its very slow 'fast' RAM interface) Warp Engine 68040/33 and a
  17. * Mark 1 Cyberstorm, which was even faster than the Mark 2 - though
  18. * it's a shame that Phase Five's Mark 1 SCSI add-on never worked as
  19. * it should have done. Nic Wilson's KickSpeed tester (from Set040)
  20. * reads ROM 2.4 times faster on my Mark 1 Cyberstorm hardware after
  21. * running QuickROM. 
  22. *
  23. * The advantages of QuickROM over the proprietary versions are:
  24. *
  25. * Allocates RAM from the top of memory to minimise fragmentation.
  26. *
  27. * Allows de-allocation as well as allocation, freeing 516K memory.
  28. *
  29. * More diagnostics for cases when it won't work (Exec result codes).
  30. *
  31. * Freely distributable including the Devpac Source code (this is it)
  32. * with copious comments explaining its strengths and weaknesses.
  33. *
  34. * Does not use undocumented 68060.library hooks, so it should work
  35. * fine on any other 68060 or 68040 system with an MMU, unlike some.
  36. *
  37. * Works with 1 Mb ROMs as well as Commodore 512K ones, and uses the
  38. * documented method to find the ROM size, so it should suit other
  39. * sizes too, as long as they're in the first 32 Mb of address space
  40. * (likely as the MAGIC_ROM_SIZE needs to be at address 16 Mb - 20).
  41. *
  42. * Limitations are:
  43. *
  44. * No messages. Check the return code to find out EXACTLY what happened.
  45. *
  46. * Requires an MMU, and won't work with old 68030, 68451 or 68851 ones.
  47. * There are already plenty of Kickstart re-mappers for those systems.
  48. *
  49. * May get confused in the MMU table setup or ROM location is radically
  50. * changed in some future Amiga. This program is inevitably architecture-
  51. * and processor-specific, although I've tried to make it fairly flexible.
  52. *
  53. * History and Predictions:
  54. *
  55. * Updated for version 37.08 for conditional inclusion of WB startup code.
  56. * Reassembly of that version requires some standard Amiga include files.
  57. *
  58. WB_START    EQU    1    0 for CLI only, 1 for icon support
  59. *
  60. * Code was originally designed to shadow the 512K ROM at $00F80000; this
  61. * suited all Commodore Amiga ROMs from Kickstart 1.4 to 3.1, but new 1Mb
  62. * versions are expected one day, so the updated code includes changes to
  63. * look for them, from address $00F00000 up. It still expects ROM sizes to
  64. * be a multiple of 256K, where that's the size of a pointer-level table
  65. * entry, as it works in units of one complete 256K mapping table.
  66. *
  67. *   The Third Edition of the Amiga Hardware Reference Manual documents
  68. *   on page 224 a technique for finding the size and hence the start
  69. *   address of the ROM, making reference to these 'magic' constants:
  70. *
  71. MAGIC_ROMEND equ    $01000000        End of C= Kickstarts
  72. MAGIC_SIZEOFFSET equ    -20        Offset to ROM size.L
  73. *
  74. * When testing modifications, check the MMU start pointer offset and
  75. * number of pointer-level entries modified in TableFix, as well as the
  76. * ROM address and size. If it's past $01FFFFFF you'll need to use a
  77. * later root pointer to find the required first pointer level entry.
  78. *
  79. * The re-mapping area includes one extra MMU page of RAM to ensure page
  80. * alignment. It uses eight bytes after the ROM image (guaranteed to be
  81. * available by heap alignment rules) to point back to the start of the
  82. * allocation and watermark the area "MMU!". All current systems use 4K
  83. * pages but some effort has been made to make the code adjust to other
  84. * page sizes, if re-assembled with the following constant adjusted:
  85. *
  86. PAGE_SIZE    equ    4096
  87. *
  88. * PLEASE NOTE: the code has not been tested with 8K pages, as they're not
  89. * used in any known Amiga; similarly it assumes 256K areas for each pointer
  90. * level table entry, as these are standard on current 68040 and 68060s. It
  91. * will probably require radical change for new or non-68040/68060 MMUs
  92. *
  93. ******************************************************************************
  94. QuickROM    
  95.     ifne    WB_START
  96.     
  97.     incdir    Devpac:include
  98.     
  99.     include    dos/dosextens.i    For startup
  100.     include    exec/exec_lib.i    For CALLEXEC
  101.  
  102. * Startup code to make a Workbench execute look like the CLI
  103. * based loosely on RKM Vol 1 page 4-36, from Devpac 3 examples,
  104. * but modified to parse the parameter supplied.
  105.  
  106.     movem.l    d0/a0,-(sp)    Save initial values
  107.     clr.l    ReturnMsg
  108.  
  109.     sub.l    a1,a1
  110.     CALLEXEC     FindTask        Find us
  111. *    move.l    d0,OurTask
  112.     move.l    d0,a4
  113.  
  114.     tst.l    pr_CLI(a4)        Who called?
  115.     beq.s    FromBench
  116.  
  117. * We were called from the Shell
  118.  
  119.     movem.l    (sp)+,d0/a0        Restore registers
  120.     bra.s    starter        Run main program
  121.  
  122. ReturnMsg    dc.l    0        Non-reentrant data!
  123. * OurTask    dc.l    0
  124.  
  125. * We were called from the Workbench
  126.  
  127. FromBench    lea.l    pr_MsgPort(a4),a0
  128.     CALLEXEC    WaitPort        Wait for a message
  129.     lea.l    pr_MsgPort(a4),a0
  130.     CALLEXEC    GetMsg        Then get it
  131.     move.l    d0,ReturnMsg    Save it for later reply
  132.     movem.l    (sp)+,d0/a0        Restore
  133.  
  134. starter    bsr.s    Main
  135.  
  136. * returns to here with exit code in d0
  137.  
  138.     move.l    d0,-(sp)        Save it
  139.  
  140.     tst.l    ReturnMsg
  141.     beq.s    ExitToDOS        If I was a CLI
  142.  
  143.     CALLEXEC     Forbid
  144.     move.l    ReturnMsg,a1    Tell Workbench we're done
  145.     CALLEXEC     ReplyMsg
  146.  
  147. ExitToDOS
  148.     move.l    (sp)+,d0        Exit code
  149.     rts
  150.  
  151.     endc
  152.     
  153. * This is the main program. It uses 68020+ opcodes as well as the MMU, so
  154. * it starts by checking ExecBase to ensure that the processor is suitable.
  155.     
  156. Main    move.l      4.w,a6                    Find EXEC
  157.     btst      #3,$129(a6)         Test for a 68060 or 68040
  158.             beq.s    Too_Old
  159.  
  160.             lea.l    FindMMU,a5            
  161.            jsr        -30(a6)            EXEC Supervisor function
  162.             tst.w    d0        Is MMU enabled in TC? If so,
  163.             bpl.s    MMU_off        bit 15=1 (on 68040/060 only)
  164.  
  165.     if    PAGE_SIZE=4096
  166.     
  167.             add.w    d0,d0        Check we're using 4K pages: if
  168.             bpl.s    Pages_OK        so, TC bit 14 should be zero
  169.  
  170. Pages_8K    moveq    #24,d0        FAIL! MMU using 8K pages
  171.     rts
  172.  
  173.     endc
  174.     
  175. Pages_OK    move.l    a0,d0        Copy and test Root Pointer
  176.             bne.s    got_MMU        Zero is definitely not enough
  177.             
  178. no_MMU    moveq    #28,d0        FAIL! MMU not initialised
  179.     rts
  180.     
  181. MMU_off    moveq    #26,d0        FAIL! MMU not enabled
  182.     rts    
  183.     
  184. Too_Old    moveq    #30,d0        FAIL! 68060 or 68040 required
  185.     rts
  186.  
  187.     dc.b    '$VER: QuickROM v36.08 (21-May-1998) by Simon N Goodwin',0
  188.     even
  189.  
  190. Bad_Copy    moveq    #20,d0        FAIL! Remapped by someone else
  191.     rts        
  192.  
  193. * EXEC Supervisor routine to extract MMU configuration register details 
  194.  
  195. FindMMU    movec    urp,a0
  196.     movec    tc,d0
  197.     rte        
  198.  
  199. No_Room    moveq    #22,d0        FAIL! More FAST RAM needed
  200.      rts
  201.  
  202. ******************************************************************************
  203. *
  204. * If we get thus far we're basically onto a winner. We've got an 060 or 040,
  205. * 4K memory mapping is enabled. Code has been extended to allow undoing, and
  206. * the memory to be reclaimed, if it is re-invoked when already in use.
  207. *
  208. * Register usage:
  209. *
  210. * D0, D1, A0, A1 scratch and system
  211. * D4 Size of physical ROM
  212. * D7 MMU table address mask
  213. *
  214. * A4 Start of physical ROM
  215. * A5 End of physical ROM
  216. *
  217. got_MMU    move.l    (a0),d0        MMU pointer table for 1st 32 Mb
  218.     move.l    #$FFFFFE00,d7    Mask to clear lower 9 bits
  219.     and.l    d7,d0        Mask allows safe .W in offset
  220.     lea.l    MAGIC_ROMEND,a5    End of ROM
  221.     move.l    a5,a4        
  222.     move.l    MAGIC_SIZEOFFSET(a5),d4 Size of ROM
  223.     moveq    #16,d1        Shift to divide start*4 by 256K
  224.     sub.l    d4,a4        Start of ROM
  225.     move.l    a4,d5
  226.     
  227. * The pointers handle 256K each, so if the ROM is at $00F80000 as usual the
  228. * first associated long word pointer will be entry 62, counting from 0, in the
  229. * pointer-level table, since 62*256K = 15.5 Mb = $00F80000 (as any fule kno).
  230.  
  231.     lsr.l    d1,d5        Expect 62*4 for ROM at $F80000
  232.     add.w    d5,d0        Offset to first page pointer
  233.     move.l    d0,a2        Save first pointer table entry
  234.     move.l    (a2),d1        Find first page table entry
  235.     and.l    d7,d1        Mask out page usage flags
  236.     move.l    (d1.l),d1        Get page table entry
  237.     and.l    d7,d1        Physical address for this page
  238.     cmp.l    a4,d1        Is it pointing at ROM already?
  239.     beq.s    Create        If so, we can soon change that!
  240.  
  241. * It's already re-mapped, so try to un-map it
  242.  
  243.     add.l    d4,d1        Point past end of ROM
  244.     move.l    d1,a1
  245.     move.l    (a1)+,d6        Pick up past pointer
  246.     beq.s    Bad_Copy        Check it's non zero!
  247.     
  248.     moveq    #7,d1        Mask for lower three bits
  249.     and.l    d6,d1          which should all be zero
  250.     bne.s    Bad_Copy        Check alignment is plausible
  251.  
  252.     cmp.l    #'MMU!',(a1)    Check for our odd signature
  253.     bne.s    Bad_Copy
  254.  
  255.     move.l    a4,d2    
  256.     bsr.s    TableFix        Point MMU tables back to ROM
  257.  
  258.     move.l    d6,a1        Where to deallocate
  259.     move.l    #PAGE_SIZE,d0
  260.     add.l    d4,d0        ROM size and a bit
  261.  
  262.     jsr    -210(a6)        FreeMem
  263.  
  264.     moveq    #0,d0        No error
  265.     rts
  266.     
  267. * Allocate memory
  268.  
  269. Create    move.l    #$00040004,d1    MEMF_REVERSE and MEMF_FAST
  270.     move.l    d4,d0        Deduced ROM size
  271.     add.l    #PAGE_SIZE,d0    ...and a bit for overlap
  272.  
  273.     jsr    -198(a6)        AllocMem
  274.  
  275.     move.l    a4,a0        Computed ROM address
  276.     move.l    d0,d2        Copy returned address
  277.     beq.s    No_Room
  278.  
  279.     move.l    d0,a3        Save base of allocated RAM
  280.     
  281. * Ensure correct alignment on a page boundary
  282.  
  283.     move.l    d4,d0        ROM size
  284.     add.l    #PAGE_SIZE-1,d2
  285.     and.l    #$FFFFFFFF-PAGE_SIZE+1,d2
  286.     move.l    d2,a1        Where to copy TO
  287.     move.l    a3,(a1,d0.l)    Store real base at end of copy
  288.     move.l    #'MMU!',4(a1,d0.l)    Put watermark in last 4 bytes
  289.     
  290. * Copy ROM there
  291.  
  292.     jsr    -624(a6)        CopyMemQuick, A0 to A1 for D0
  293.  
  294. * This subroutine updates the MMU page table, whether mapping or unmapping
  295.         
  296. TableFix    jsr        -120(a6)            Disable, implies Forbid
  297.  
  298. * Fix the MMU tables by pointing them at the new copy
  299. * D2 points at the 'new' ROM image to be used, and D4 is its size.
  300. * A2 points to the MMU pointer table entry for the first 256K of ROM space
  301.  
  302.     move.l    d4,d1        Work out size in pointer pages
  303.     moveq    #18,d0        Shift factor to divide by 256K
  304.     lsr.l    d0,d1        Number of pointers to be tweaked
  305.     addq.l    #1,d2        Set Resident flag for pages
  306.     subq.l    #1,d1        Adjust for DBRA
  307.  
  308. Pointers    move.l    d7,d0
  309.     and.l    (a2)+,d0        Pointer to MMU block to remap
  310.     move.l    d0,a0        Masked to 512 boundary
  311.     moveq    #63,d0        Count 4K blocks
  312.  
  313. Pages    move.l    d2,(a0)+        Masked page pointer
  314.     add.l    #PAGE_SIZE,d2
  315.     dbra    d0,Pages
  316.  
  317.     dbra    d1,Pointers
  318.  
  319.     jsr        -126(a6)            Enable, implies Permit
  320.     
  321.     moveq    #0,d0        Admit nothing
  322.     rts
  323.     
  324.     end
  325.